<template>
  <div>
    <a-input @click="showSelectUser" v-model="showValue" select-model="single" readOnly>
      <a-icon slot="suffix" type="user-add" />
    </a-input>
    <ant-modal
      :visible="open"
      :modal-title="modalTitle"
      :adjust-size="false"
      @cancel="cancel"
      modalHeight="480"
      modalWidth="800"
      dialogClass="personSelect">
      <a-row slot="content">
        <a-spin :spinning="spinning" :delay="delayTime" tip="Loading...">
          <a-col class="treeBox treeborder" :span="12">
            <a-input-search placeholder="请输入用户信息" @search="search" />
            <div class="personSelectTree">
              <a-table
                class="ant-table-striped"
                :hideDefaultSelections="true"
                :hideSelectAll="true"
                :columns="columns"
                :data-source="list"
                :loading="loading"
                rowKey="userId"
                :bordered="false"
                :sticky="true"
                size="middle"
                tableKey="system-user-SysUserIndex-table"
                @refresh="getList"
                :row-selection="{ selectedRowKeys: selectedKeys, onChange: onSelectChange, onSelect: onSelect, onSelectAll: onSelectAll }"
                :format-conditions="true"
                :scroll="{
                  scrollToFirstRowOnChange: true,
                  y: 300
                }"
                :pagination="{
                  current: queryParam.pageNum,
                  pageSize: queryParam.pageSize,
                  total: total,
                  showLessItems: true,
                  showQuickJumper: true,
                }"
              >
              </a-table>
            </div>
          </a-col>
          <a-col :span="12">
            <div class="contentBox">
              <div :style="{ padding: '10px 20px' }">
                <a-checkbox :indeterminate="indeterminate" @change="onCheckAllChange" :checked="checkAll">
                  已选（{{ selectCount }}）</a-checkbox>
                <a-icon :style="{ float: 'right' }" type="delete" @click="deleteSelectUser" />
              </div>
              <a-checkbox-group v-model="userCheckedList" @change="onChange">
                <a-list item-layout="horizontal" :data-source="userdata" ref="editTable">
                  <a-list-item slot="renderItem" slot-scope="item">
                    <a-checkbox :value="item.id" @change="checkBoxOnChange" />
                    <a-list-item-meta>
                      <template slot="title">
                        <span class="title-name">{{ item.name }}</span>
                        <span class="title-dept">({{ item.subtitle }})</span>
                      </template>
                      <a-avatar slot="avatar" :icon="item.icon" />
                    </a-list-item-meta>
                    <template slot="actions">
                      <a-icon type="drag" class="dragIconClass" v-if="selectModel === 'multi'" />
                      <a-icon type="close-circle" @click="deletSelectUser(item.id)" />
                    </template>
                  </a-list-item>
                </a-list>
              </a-checkbox-group>
            </div>
          </a-col>
        </a-spin>
      </a-row>

      <template slot="footer">
        <a-button @click="cancel">取消</a-button>
        <a-button type="primary" @click="saveSelectUser">保存</a-button>
      </template>
    </ant-modal>
  </div>
</template>
<script>
  import allIcon from '@/core/icons'
  import { listUser, listUserInfoByIds } from '@/api/system/user'
  import AntModal from '@/components/pt/dialog/AntModal'
  import Sortable from 'sortablejs' // 列交换第三方插件
  import AdvanceTable from '@/components/pt/table/AdvanceTable'
  export default {
    props: {
      modalTitle: {
        type: String,
        default: '人员选择'
      },
      // 默认值
      defaultValue: {
        required: false,
        default: null
      },
      // 返回数据
      value: {
        required: false
      },
      // 单选 single ，多选 multi
      selectModel: {
        type: String,
        required: false,
        default: 'single'
      },
      maxSelect: {
        type: Number,
        required: false,
        default: 0
      }
    },
    data() {
      return {
        showValue: '',
        oldValue: '',
        indeterminate: false,
        checkAll: false,
        userCheckedList: [],
        spinning: false,
        delayTime: 200,
        allIcon,
        sortable: undefined,
        replaceFields: {
          children: 'children',
          key: 'id',
          value: 'id'
        },
        open: false,
        expandedKeys: [],
        autoExpandParent: true,
        selectedKeys: [], // 左侧所有选中节点
        select: {
          ids: '',
          names: ''
        }, // 最终选择用户对象
        searchValue: '',
        userdata: [],
        checkedUser: [],
        selectCount: 0,

        // 日期范围
        list: [],
        colorList: ['#F38709', '#813AFD', '#00C4AA', '#4B7AEE'],
        tableTitle: '用户管理',
        selectedRowKeys: [],
        selectedRows: [],
        loading: false,
        total: 0,
        dateRange: [],
        labelCol: { span: 6 },
        wrapperCol: { span: 18 },
        queryParam: {
          pageNum: 1,
          pageSize: 10,
          beginTime: undefined,
          endTime: undefined,
          username: undefined,
          name: undefined,
          phone: undefined,
          status: undefined,
          deptId: undefined
        },
        columns: [
          {
            title: '姓名',
            dataIndex: 'name'
          },
          {
            title: '登录名',
            dataIndex: 'username'
          },
          {
            title: '部门',
            dataIndex: 'deptName'
          }
        ]
      }
    },
    components: {
      AntModal,
      allIcon,
      AdvanceTable
    },
    created() {
      this.getList()
    },
    mounted() {},
    watch: {
      userdata: {
        immediate: true,
        handler(val) {
          this.selectCount = val.length
          if (this.selectModel === 'multi' && val.length > 0 && this.sortable === undefined) {
            this.rowDrop()
          }
        }
      },
      select: {
        immediate: true,
        handler(val) {
          this.oldValue = this.select && this.select.names ? this.select.names : ''
          this.showValue = this.oldValue
        }
      },
      value: {
        immediate: true,
        handler(newV) {
          if (newV) {
            this.select = newV
          } else {
            this.select = {
              ids: '',
              names: ''
            }
          }
        }
      }
    },
    methods: {
      search(value, e) {
        this.queryParam.name = value
        this.getList()
      },
      /** 查询列表 */
      getList() {
        this.loading = true
        listUser(this.queryParam).then(result => {
          this.list = result.data.list
          this.total = result.data.totalCount
          this.loading = false
        }).catch(e => {
          this.loading = false
        })
      },
      /** 搜索按钮操作 */
      handleQuery() {
        this.queryParam.pageNum = 1
        this.getList()
      },
      /** 重置按钮操作 */
      resetQuery() {
        this.dateRange = []
        this.queryParam = {
          pageNum: 1,
          pageSize: 10,
          beginTime: undefined,
          endTime: undefined,
          username: undefined,
          name: undefined,
          phone: undefined,
          status: undefined,
          deptId: undefined
        }
        this.handleQuery()
      },
      onSelectChange(selectedRowKeys, selectedRows) {
        this.selectedKeys = selectedRowKeys
      },
      onSelect(record, selected, selectedRows, nativeEvent) {
        // 左侧选择用户时触发
        if (selected) {
          this.setSelectedUserInfo(record.userId, record.name, record.deptName)
        } else {
          this.removeSelectedUserInfo(record.userId)
        }
      },
      onSelectAll(selected, selectedRows, changeRows) {
        if (selected) {
          changeRows.forEach(record => {
            this.setSelectedUserInfo(record.userId, record.name, record.deptName)
          })
        } else {
          changeRows.forEach(record => {
            this.removeSelectedUserInfo(record.userId)
          })
        }
      },
      // 刚刚进入组件时，初始化已选
      getSelectUserInfo() {
        if (this.select.ids !== undefined && this.select.ids !== 'undefined' && this.select.ids !== '') {
          listUserInfoByIds(this.select.ids).then(response => {
            this.userdata = []
            this.selectedKeys = []
            response.data.forEach(record => {
              this.setSelectedUserInfo(record.userId, record.name, record.deptName)
            })
          })
        }
      },
      // 右侧已选择框勾选改变时触发
      checkBoxOnChange(e) {
        if (e.target.checked) {
          this.checkedUser.push(e.target.value)
        } else {
          this.checkedUser = this.checkedUser.filter(function(item) {
            return item !== e.target.value
          })
        }
      },
      onChange(checkedList) {
        // 右侧已选用户复选框勾选触发
        this.indeterminate = !!this.checkedUser.length && this.checkedUser.length < this.userdata.length
        this.checkAll = this.checkedUser.length === this.userdata.length
      },
      onCheckAllChange(e) {
        // 右侧已选用户全选按钮触发 解决漏洞
        Object.assign(this, {
          userCheckedList: e.target.checked ? this.selectedKeys : [],
          checkedUser: e.target.checked ? this.selectedKeys : [],
          indeterminate: false,
          checkAll: e.target.checked
        })
      },
      deleteSelectUser() {
        // 右侧已选用户上方删除按钮，全选和勾选删除
        if (this.checkAll) {
          // 全选状态下直接清空数据
          this.checkedUser = []
          this.userdata = []
          this.selectedKeys = []
          this.checkAll = false
        } else {
          // 移除已勾选数据
          this.userCheckedList.forEach(checkItem => {
            this.removeSelectedUserInfo(checkItem)
          })
        }
      },
      deletSelectUser(id) {
        // 右侧已选用户悬浮删除按钮删除方法
        this.removeSelectedUserInfo(id)
      },
      resetSelectUserInfo() {
        this.selectedKeys = []
        this.userdata = []
      },
      showSelectUser() {
        this.getSelectUserInfo()
        this.open = true
        this.resetSelectUserInfo()
      },
      callback(key) {
        console.log(key)
      },
      cancel(e) {
        this.$emit('close')
        this.open = false
      },
      unique(arr) {
        // 数据去重
        const res = new Map()
        return arr.filter(arr => !res.has(arr.id) && res.set(arr.id, 1))
      },
      setSelectUserInfo(checkedNodes) {
        // 过滤掉部门数据
        checkedNodes.forEach(node => {
          const name = node.componentOptions.propsData.dataRef.title
          const id = node.componentOptions.propsData.dataRef.id
          const subtitle = node.componentOptions.propsData.dataRef.attributes.subtitle
          this.setSelectedUserInfo(id, name, subtitle)
        })
      },
      setSelectUserInfoByNodes(checkedNodes) {
        // 专门处理直接通过勾选父节点展开数据后的选人操作
        checkedNodes.forEach(node => {
          const name = node.title
          const id = node.id
          const subtitle = node.attributes.subtitle
          this.setSelectedUserInfo(id, name, subtitle)
        })
      },

      removeSelectedUserInfo(userId) {
        const id = userId
        this.selectedKeys = this.selectedKeys.filter(function (item) {
          return item !== id
        })
        this.userdata = this.userdata.filter(function (item) {
          return item.id !== id
        })
      },
      setSelectedUserInfo(id, name, subtitle) {
        this.selectedKeys.push(id)
        const selectUser = {
          id: id,
          name: name,
          subtitle: subtitle,
          icon: 'user'
        }
        this.userdata.push(selectUser)
        this.userdata = this.unique(this.userdata)
      },
      saveSelectUser() {
        // 保存选中数据
        let ids = ''
        let names = ''
        if (this.selectModel === 'single' && this.userdata.length > 1) {
          this.$message.warning(`只能选择1人！`)
          return
        }

        if (this.userdata.length > this.maxSelect && this.maxSelect !== 0) {
          this.$message.warning(`已设置最多选择${this.maxSelect}人！`)
          return
        }
        this.userdata.forEach(function(node, index) {
          if (index > 0) {
            ids += ','
            names += ','
          }
          ids = ids + node.id
          names = names + node.name
        })
        this.showValue = names
        const result = {
          ids,
          names
        }
        this.$emit('change', result)
        this.$nextTick(() => {
          this.select = result
          // 双向绑定
          this.$emit('input', result)
          this.$emit('callBack', result)
        })
        this.open = false
      },
      /**
       * 行拖拽事件
       */
      rowDrop() {
        const that = this
        this.$nextTick(() => {
          const xGrid = this.$refs.editTable
          const el = xGrid.$el.querySelector('.ant-list-items')
          this.sortable = Sortable.create(el, {
            handle: '.ant-list-item',
            animation: 300,
            delay: 100,
            chosenClass: 'select-list-color', // 被选中项的css 类名
            dragClass: 'drag-list-color', // 正在被拖拽中的css类名
            onEnd: ({
              newIndex,
              oldIndex
            }) => {
              const currRow = that.userdata.splice(oldIndex, 1)[0]
              that.userdata.splice(newIndex, 0, currRow)
              // this.$emit('rowDrop', this.userdata)
            },
            onUpdate(event) {
              const newIndex = event.newIndex
              const oldIndex = event.oldIndex
              const $body = el
              const $tr = $body.children[newIndex]
              const $oldTr = $body.children[oldIndex]
              // 先删除移动的节点
              $body.removeChild($tr)
              // 再插入移动的节点到原有节点，还原了移动的操作
              if (newIndex > oldIndex) {
                $body.insertBefore($tr, $oldTr)
              } else {
                $body.insertBefore($tr, $oldTr.nextSibling)
              }
            }
          })
        })
      }
    }
  }
</script>
<style lang="less">
  .ant-tree-checkbox-disabled {
  }

  body .ant-tree li .ant-tree-node-content-wrapper .depIcon {
    color: #666666;
    font-size: 20px;
  }

  .personSelect .ant-modal-body {
    padding: 0;
  }

  .personSelectTree {
    height: 325px;
    overflow: auto;
    padding: 0 4px;
  }

  .personSelect {
    .ant-tabs-bar {
      margin: 0;
    }

    .treeborder {
      border-right: 1px solid #e8e8e8;
    }

    .treeBox {
      padding: 0;

      .ant-input-search {
        width: 100%;
        padding: 10px 15px 5px;
      }

      .ant-input-affix-wrapper .ant-input-suffix {
        right: 22px;
      }

      .ant-tree-checkbox {
        padding: 8px 0 0;
      }

      .ant-tree-checkbox-checked::after {
        border: none;
      }

      .ant-tree li .ant-tree-node-content-wrapper {
        width: calc(100% - 40px);
      }
    }

    .contentBox {
      padding: 0;

      .ant-list-items {
        margin: 0 10px;
      }

      .ant-avatar {
        width: 30px;
        height: 30px;
        line-height: 30px;
        background: #47b5e6;
      }

      .ant-checkbox-wrapper {
        font-size: 12px;
      }

      .ant-checkbox-group {
        display: block;
        height: 330px;
        overflow: auto;
      }

      .ant-list-item-meta-avatar {
        margin-right: 0;
      }

      .ant-list-item-meta-title {
        line-height: 30px;
        font-size: 12px;
        margin-bottom: 0px;
      }

      .ant-avatar.ant-avatar-icon {
        margin: 0 10px;
      }

      .ant-list-item-action>li {
        padding: 0 5px;
      }

      .ant-list-split .ant-list-item {
        border-bottom: 0;
        padding: 5px 10px;

        .ant-list-item-action {
          display: none;
          margin-left: 0;
        }

        .title-name {
          color: #323232;
          margin-right: 5px;
        }

        .title-dept {
          color: #a5a5a5;
        }
      }

      .ant-list-item:hover {
        background: #f0f6ff;
        cursor: move;

        .ant-list-item-action {
          display: block;
        }
      }

      .select-list-color {
        box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);
        z-index: 9999;
      }

      .ant-list-item-action .ant-list-item-action-split {
        width: 0;
      }
    }

    .ant-tabs.ant-tabs-card .ant-tabs-card-bar .ant-tabs-tab {
      margin-right: 0px;
      margin-top: 0px;
      height: 40px;
      line-height: 40px;
      border: 0;
      border-right: 1px solid #fff;
      background: #f3f3f3;
      border-radius: 0;
    }

    .ant-tabs.ant-tabs-card .ant-tabs-card-bar .ant-tabs-tab-active {
      background: #fff;
    }

    .ant-tabs.ant-tabs-card .ant-tabs-card-bar .ant-tabs-nav-wrap {
      padding: 0 10px;
      background: #f3f3f3;
    }
  }
</style>
